package com.mayikt.pay.callback.union;

import com.alibaba.fastjson.JSONObject;
import com.mayikt.constants.Constants;
import com.mayikt.pay.callback.template.AbstractPayCallbackTemplate;
import com.mayikt.pay.mapper.PaymentTransactionMapper;
import com.mayikt.pay.mapper.entity.PaymentTransaction;
import com.mayikt.pay.mq.producer.Producer;
import com.mayikt.pay.sdk.union.AcpService;
import com.mayikt.pay.sdk.union.LogUtil;
import com.mayikt.pay.sdk.union.SDKConstants;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.Map;

/**
 * 银联回调处理方法
 */
@Component
public class UnionPayCallback extends AbstractPayCallbackTemplate {
    @Autowired
    private PaymentTransactionMapper paymentTransactionMapper;
    @Autowired
    private Producer producer;
    @Override
    public Map<String, String> verifySignature(HttpServletRequest req, HttpServletResponse res) {
        LogUtil.writeLog("BackRcvResponse接收后台通知开始");

        String encoding = req.getParameter(SDKConstants.param_encoding);
        // 获取银联通知服务器发送的后台通知参数
        Map<String, String> reqParam = getAllRequestParam(req);
        LogUtil.printRequestLog(reqParam);

        //重要！验证签名前不要修改reqParam中的键值对的内容，否则会验签不过
        if (!AcpService.validate(reqParam, encoding)) {
            LogUtil.writeLog("验证签名结果[失败].");
            //验签失败，需解决验签问题
            reqParam.put("verifyResult","201");
        } else {
            LogUtil.writeLog("验证签名结果[成功].");
            //【注：为了安全验签成功才应该写商户的成功处理逻辑】交易成功，更新商户订单状态

            String orderId =reqParam.get("orderId"); //获取后台通知的数据，其他字段也可用类似方式获取
            String respCode = reqParam.get("respCode");
            //判断respCode=00、A6后，对涉及资金类的交易，请再发起查询接口查询，确定交易成功后更新数据库。
            reqParam.put("verifyResult","200");
            reqParam.put("paymentId",orderId);
        }
        LogUtil.writeLog("BackRcvResponse接收后台通知结束");
        return reqParam;
    }

    @Override
    public String failResult() {
        return Constants.HTTP_RES_CODE_201.toString();
    }

    @Override
    public String successResult() {
        return "OK";
    }

    @Override
    public String asyncService(Map<String,String> map) {
        String orderId = map.get("orderId");
        String resCode = map.get("respCode");
        //判断是否支付成功
        if (!"00".equals(resCode) || "A6".equals(resCode)){
            return failResult();
        }
        //将状态改为已支付状态
        int row = paymentTransactionMapper.updateStaByorderId(orderId,1);
        if (row == 0){
            return failResult();
        }
        //进行积分增加
        PaymentTransaction paymentTransaction = paymentTransactionMapper.selByOrderId(orderId);
        addMQIntegral(paymentTransaction);
        int x = 1/0;
        return successResult();
    }


    public static Map<String, String> getAllRequestParam(
            final HttpServletRequest request) {
        Map<String, String> res = new HashMap<>();
        Enumeration<?> temp = request.getParameterNames();
        if (null != temp) {
            while (temp.hasMoreElements()) {
                String en = (String) temp.nextElement();
                String value = request.getParameter(en);
                res.put(en, value);
                // 在报文上送时，如果字段的值为空，则不上送<下面的处理为在获取所有参数数据时，判断若值为空，则删除这个字段>
                if (res.get(en) == null || "".equals(res.get(en))) {
                    // System.out.println("======为空的字段名===="+en);
                    res.remove(en);
                }
            }
        }
        return res;
    }

    @Async  //开启异步线程
    public void addMQIntegral(PaymentTransaction paymentTransaction){
        JSONObject jsonObject = new JSONObject();
        jsonObject.put("paymentId",paymentTransaction.getPaymentId());
        jsonObject.put("userId",paymentTransaction.getUserId());
        jsonObject.put("integral",100);
        producer.send(jsonObject);
    }
}
